using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace BepuPhysics.CollisionDetection
{
    /// <summary>
    /// 打包间接指向与配对高速缓存条目相关联的数据。
    /// </summary>
    public struct PairCacheIndex
    {
        internal ulong packed;

        /// <summary>
        /// 获取此索引是否实际引用任何内容。仅当为真时才应使用Type和Index。
        /// </summary>
        public bool Exists
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (packed & (1UL << 63)) > 0; }
        }

        /// <summary>
        /// 获取此索引是否引用活动缓存项。如果为False,则该项目存在于非活动集合中。
        /// </summary>
        public bool Active
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (packed & (1UL << 62)) > 0; }
        }


        /// <summary>
        /// 获取拥有该项的缓存的索引。
        /// </summary>
        public int Cache
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (int)(packed >> 38) & 0x3FFFFF; } // 24位
        }

        /// <summary>
        /// 获取该对象的类型索引。
        /// </summary>
        public int Type
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (int)(packed >> 30) & 0xFF; } // 8位
        }

        /// <summary>
        /// 获取特定于类型的列表中的对象的索引。
        /// </summary>
        public int Index
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return (int)(packed & 0x3FFF_FFFF); } // 30位
        }


        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public PairCacheIndex(int cache, int type, int index)
        {
            Debug.Assert(cache >= 0 && cache < (1 << 24), "Do you really have that many threads, or is the index corrupt?");
            Debug.Assert(type >= 0 && type < (1 << 8), "Do you really have that many type indices, or is the index corrupt?");
            // 请注意,在最高有效的2位中包括一个设置位。
            // MSB编码索引是显式构造的,因此它是一个"真实"引用。
            // 默认构造的PairCacheIndex在MSB中将具有0,因此我们可以对空引用使用默认构造函数。
            // 第二个最高有效位设置有效标志。此构造函数仅由活动引用使用。
            packed = (ulong)((3L << 62) | ((long)cache << 38) | ((long)type << 30) | (long)index);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static PairCacheIndex CreateInactiveReference(int cache, int type, int index)
        {
            Debug.Assert(cache >= 0 && cache < (1 << 24), "Do you really have that many sets, or is the index corrupt?");
            Debug.Assert(type >= 0 && type < (1 << 8), "Do you really have that many type indices, or is the index corrupt?");
            // 请注意,在最高有效的2位中包括一个设置位。
            // MSB编码索引是显式构造的,因此它是一个"真实"引用。
            // 默认构造的PairCacheIndex在MSB中将具有0,因此我们可以对空引用使用默认构造函数。
            // 第二个最高有效位未置位。此函数仅创建非活动引用。
            PairCacheIndex toReturn;
            toReturn.packed = (ulong)((1L << 63) | ((long)cache << 38) | ((long)type << 30) | (long)index);
            return toReturn;
        }

        public override string ToString()
        {
            return $"{{{Cache}, {Type}, {Index}}}";
        }

    }
}
